#pragma once

#include <opencv2/opencv.hpp>
#include "opencv2/imgcodecs/legacy/constants_c.h"
#include "opencv2/imgproc/types_c.h"

#include "utils.h"
#include "acl/acl.h"
#include "dimp/model_process.h"
#include "dimp/preprocess_for_init.hpp"
#include <memory>
#include <vector>

using namespace std;
using namespace cv;

struct Nodes{
    void* firstaddr;
    uint32_t size;
};

/**
* ObjectDetect
*/
class Dimp_Init{
public:
    Dimp_Init(const char* modelPath);
    ~Dimp_Init();
    //Inference initialization
    Result Init(int32_t& d, aclrtContext& c, aclrtStream& s, aclrtRunMode& runMode);
    //nference frame image preprocessing
    Result LoadInputData(vector<cv::Mat> transform_imgs, vector<Target_Box> transform_boxes);
    //Inference frame picture
    Result Inference();
   
    void DestroyResource();

    Nodes layer2_;


    Nodes weights_;

    Nodes modulation1_;

    Nodes modulation2_;

    Nodes classifier_feats_;
    
private:
    //Loading reasoning model
    Result InitModel(const char* omModelPath);
    Result CreateModelInputdDataset();
    //Establish a connection to the Presenter Server
    Result OpenPresenterChannel();
    //Get data from model inference output aclmdlDataset to local
    void* GetInferenceOutputItem(uint32_t& itemDataSize,
    aclmdlDataset* inferenceOutput,
    uint32_t idx);
    //Serializes a frame image into a data stream
    //Release the requested resources

private:
     int32_t deviceId_;
    aclrtContext context_;
    aclrtStream stream_;
    ModelDimpProcess initmodel_; //Inference model instance

    const char* modelPath_; //Offline model file path
    uint32_t modelWidth_;   //The input width required by the model
    uint32_t modelHeight_;  //The model requires high input
    uint32_t imageDataSize_; //Model input data size
    void*    imageDataBuf_;      //Model input data cache
    uint32_t initBoxSize_;
    void*    initBoxBuf_;
    uint32_t transformBoxesSize_;
    void*    transformBoxesBuf_;
    aclrtRunMode runMode_;   //Run mode, which is whether the current application is running on atlas200DK or AI1
    float transformBoxes_[13][5];
    float initBox_[5];
    uint32_t totalSize_;

    bool isInited_;     //Initializes the tag to prevent inference instances from being initialized multiple times
};

